#include <string.h>
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
//派生类中定义自己的数据成员，同时定义复制控制函数
class Base{
public:
    Base(const char * pstr)
    :_base(new char[strlen(pstr) + 1]())
    {
        strcpy(_base, pstr);
    }


    Base(const Base & rhs)
    :_base(new char[strlen(rhs._base) + 1]())
    {
        strcpy(_base, rhs._base);
    }
    //赋值运算符
    Base & operator=(const Base & rhs){
        if(this != &rhs){
            delete [] _base;
            _base = new char[strlen(rhs._base) + 1]();
            strcpy(_base, rhs._base);
        }
        return *this;
    }
    ~Base(){
        if(_base){
            delete [] _base;
            _base = nullptr;
        }
    }

protected:
    char * _base;
};
//派生类中定义一个char *数据成员，使用的是深拷贝
class Derived : public Base{
public:
    Derived(const char * base, const char * derived)
    :Base(base)
    ,_derived(new char[strlen(derived) + 1]())
    {
        strcpy(_derived, derived);
        cout << "Derived(const char *)" << endl;
    }
    friend ostream & operator<<(ostream & os, const Derived & rhs);

    ~Derived(){
        if(_derived){
            delete [] _derived;
            _derived = nullptr;
        }
    }
    //拷贝构造函数
    //依然需要调用基类的构造函数来完成基类数据成员的初始化
    //Base(rhs)为什么可以这么去写？？？？向上转型
    //实际上此处调用的是Base的拷贝构造函数
    //形参和实参相结合const Base & rhs = derived;
    Derived(const Derived & rhs)
    :Base(rhs)
    ,_derived(new char[strlen(rhs._derived) + 1]())
    {
        strcpy(_derived, rhs._derived);
    }

    //赋值运算符
    //此时的赋值运算符函数是有问题的，只可以完成
    //派生类部分的赋值操作不可以完成基类的部分
    Derived & operator=(const Derived & rhs){
        if(this != &rhs){
            //需要加上这步操作，主动调用基类的赋值运算符函数
            Base::operator=(rhs);
            delete [] _derived;
            _derived = new char[strlen(rhs._derived) + 1]();
            strcpy(_derived, rhs._derived);
        }
        return *this;
    }

private:
    char * _derived;
};
ostream & operator<<(ostream & os, const Derived & rhs){
    os << rhs._base << ":::" << rhs._derived;
    return os;
}


void test(){
    Derived d1("hello", "world");
    cout << d1 << endl;
    Derived d2 = d1;
    cout << d2 << endl;
    cout << "====================" << endl;
    Derived d3("ansidadsa", "ajlsdakqwljeklqw");
    d1 = d3;
    cout << d1 << endl;
}

int main()
{
    test();
    return 0;
}

